package cn.fsd.service.impl;

import cn.fsd.domain.*;
import cn.fsd.dto.ExchangeOrderDTO;
import cn.fsd.dto.OrderDTO;
import cn.fsd.exception.CustomerException;
import cn.fsd.exception.CustomerExceptionCodeMsg;
import cn.fsd.mapper.Customer_addressMapper;
import cn.fsd.mapper.Exchange_recordMapper;
import cn.fsd.mapper.OrderMapper;
import cn.fsd.nacos.DeliveryServer;
import cn.fsd.nacos.DispatchServer;
import cn.fsd.nacos.StoreRoomServer;
import cn.fsd.query.customer.OrderQuery;
import cn.fsd.query.delivery.PurchaseBean;
import cn.fsd.service.OrderService;
import cn.fsd.vo.OrderCommodityVO;
import cn.fsd.vo.OrderVO;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    final OrderMapper orderMapper;
    final Customer_addressMapper addressMapper;
    final
    Exchange_recordMapper exchange_recordMapper;
    final StoreRoomServer storeRoomServer;
    final
    DispatchServer dispatchServer;
    final
    DeliveryServer deliveryServer;


    @Autowired
    public OrderServiceImpl(OrderMapper orderMapper, Customer_addressMapper addressMapper, StoreRoomServer storeRoomServer, DispatchServer dispatchServer, DeliveryServer deliveryServer, Exchange_recordMapper exchange_recordMapper) {
        this.orderMapper = orderMapper;
        this.addressMapper = addressMapper;
        this.storeRoomServer = storeRoomServer;
        this.dispatchServer = dispatchServer;
        this.deliveryServer = deliveryServer;
        this.exchange_recordMapper = exchange_recordMapper;
    }

    @Override
    public List<OrderCommodityVO> getOrdersOfCustomer(String customer_id) {
        List<OrderCommodityVO> orderCommodityVOList = new ArrayList<>();
        List<Order> orders = orderMapper.selectByCustomerId(customer_id);
        List<String> commodity_ids = new ArrayList<>();
        for (Order order : orders) {
            commodity_ids.add(order.getCommodity_id());
        }
        List<Commodity> commodities = deliveryServer.getCommodityPatch(commodity_ids);
        for (int i = 0; i < orders.size(); i++) {
            orderCommodityVOList.add(new OrderCommodityVO(orders.get(i), commodities.get(i)));
        }
        return orderCommodityVOList;
    }

    @Override
    public Order getOrderById(String orderId) {
        return orderMapper.selectByPrimaryKey(orderId);
    }

    //todo 需要优化速度
    @Override
    public PageInfo<OrderVO> findVOByConditionByPage(OrderQuery orderQuery) {
        PageHelper.startPage(orderQuery.getPageNow(), orderQuery.getPageSize());
        List<OrderVO> orderVOList = orderMapper.selectVOByCondition(orderQuery);
        return new PageInfo<>(orderVOList);
    }

    /**
     * 创建新订订单的接口
     */
    @Override
    public void newPurchaseOrder(OrderDTO orderDTO) {
        //订单结构转换
        Order order = orderDTO.DTO2Order();
        order.setOrder_type("新订");
        if(orderMapper.insert(order)==1){
            dispatchServer.transferById(order.getOrder_id());
        }

        if (checkStockOutByTransfer(order)) {
            //缺货
            order.setOrder_status("缺货");
            order.setDelivery_status("缺货");
            //记录缺货量，加入等待处理队列
            storeRoomServer.stockOutOP(order);
        } else {
            //不缺货时，直接分配货物，状态变为“已挂起”
            order.setDelivery_status("正常");
            //库房分配货物
            storeRoomServer.handle(order);
            order.setOrder_status("已挂起");
        }
        //订单状态为“缺货”或“已挂起”,更新订单状态
        orderMapper.updateByPrimaryKey(order);
    }


    // TODO: 2023/7/13 退订订单内容补充
    // TODO: 2023/7/14 删除对应的任务单和调度单
    @Override
    public void cancelOrder(String order_id) throws CustomerException {
        Order record = orderMapper.selectByPrimaryKey(order_id);
        if (!record.getOrder_status().equals("缺货")
                && !record.getOrder_status().equals("可分配")
                && !record.getOrder_status().equals("已挂起")) {
            throw new CustomerException(CustomerExceptionCodeMsg.ORDER_CANNOT_CANCEL);
        }
        storeRoomServer.cancelOrder(record);
        record.setOrder_status("已撤销");
        orderMapper.updateByPrimaryKey(record);
        //拷贝对象
        Order canceledOrder =new Order();
        BeanUtils.copyProperties(record,canceledOrder);
        canceledOrder.setOrder_id(String.valueOf(UUID.randomUUID()));
        canceledOrder.setOrder_type("退订");
        canceledOrder.setOrder_date(new Date());

        orderMapper.insert(canceledOrder);
    }

    @Override
    public String newExchangeOrder(ExchangeOrderDTO exchangeOrderDTO) {
        Order order = orderMapper.selectByPrimaryKey(exchangeOrderDTO.getOrder_id());
        if(!order.getOrder_status().equals("已完成")){
            throw new CustomerException(CustomerExceptionCodeMsg.ORDER_CANNOT_EXCHANGE);
        }
        if(exchange_recordMapper.selectByOrderId(order.getOrder_id())!=null){
            throw new CustomerException(CustomerExceptionCodeMsg.ORDER_ALREADY_EXCHANGE);
        }

        //拷贝对象
        Order exchangeOrder =new Order();
        BeanUtils.copyProperties(order,exchangeOrder);


        exchangeOrder.setOrder_id(String.valueOf(UUID.randomUUID()));
        exchangeOrder.setOperator_id(exchangeOrderDTO.getOperator_id());
        exchangeOrder.setOrder_type("换货");
        exchangeOrder.setOrder_date(new Date());


        //插入order，调拨生成调拨单和送货任务单
        orderMapper.insert(exchangeOrder);
        dispatchServer.transferById(exchangeOrder.getOrder_id());

        if (checkStockOutByTransfer(exchangeOrder)) {
            exchangeOrder.setOrder_status("缺货");
            exchangeOrder.setDelivery_status("缺货");
            storeRoomServer.stockOutOP(exchangeOrder);
        } else {
            exchangeOrder.setDelivery_status("正常");
            storeRoomServer.handle(exchangeOrder);
            exchangeOrder.setOrder_status("已挂起");
        }
        orderMapper.updateByPrimaryKey(exchangeOrder);

        Exchange_record exchange_record = new Exchange_record();

        exchange_record.setCustomer_id(order.getCustomer_id());
        exchange_record.setExchange_id(String.valueOf(UUID.randomUUID()));
        exchange_record.setOld_order_id(order.getOrder_id());
        exchange_record.setNew_task_id(dispatchServer.getTaskIdByOrderId(exchangeOrder.getOrder_id()));
        exchange_record.setAfter_sales("换货");
        exchange_record.setReason(exchangeOrderDTO.getReason());
        exchange_record.setExchange_num(order.getCommodity_num());
        exchange_record.setExchange_money(order.getOrder_total_amount());
        exchange_record.setExchange_date(new Date());
        exchange_recordMapper.insert(exchange_record);
        return exchangeOrder.getOrder_id();
    }

    // TODO: 2023/7/14 已进行退货或换货的订单不能再退换货
    @Override
//    @Transactional(rollbackFor = Exception.class)
    public String newReturnOrder(ExchangeOrderDTO exchangeOrderDTO) {
        Order order = orderMapper.selectByPrimaryKey(exchangeOrderDTO.getOrder_id());
        if(!order.getOrder_status().equals("已完成")){
            throw new CustomerException(CustomerExceptionCodeMsg.ORDER_CANNOT_EXCHANGE);
        }
        if(exchange_recordMapper.selectByOrderId(order.getOrder_id())!=null){
            throw new CustomerException(CustomerExceptionCodeMsg.ORDER_ALREADY_EXCHANGE);
        }
        //拷贝对象
        Order exchangeOrder =new Order();
        BeanUtils.copyProperties(order,exchangeOrder);


        exchangeOrder.setOrder_id(String.valueOf(UUID.randomUUID()));
        exchangeOrder.setOperator_id(exchangeOrderDTO.getOperator_id());
        exchangeOrder.setOrder_type("退货");
        exchangeOrder.setOrder_date(new Date());
        exchangeOrder.setOrder_status("可分配");

        //插入order，调拨生成调拨单和送货任务单
        orderMapper.insert(exchangeOrder);
        // 退货只生成退货任务单
        dispatchServer.transferById(exchangeOrder.getOrder_id());


        Exchange_record exchange_record = new Exchange_record();

        exchange_record.setCustomer_id(order.getCustomer_id());
        exchange_record.setExchange_id(String.valueOf(UUID.randomUUID()));
        exchange_record.setOld_order_id(order.getOrder_id());
        exchange_record.setNew_task_id(dispatchServer.getTaskIdByOrderId(exchangeOrder.getOrder_id()));


        exchange_record.setAfter_sales("退货");
        exchange_record.setReason(exchangeOrderDTO.getReason());
        exchange_record.setExchange_num(order.getCommodity_num());
        exchange_record.setExchange_money(order.getOrder_total_amount());
        exchange_record.setExchange_date(new Date());

        exchange_recordMapper.insert(exchange_record);

        return exchangeOrder.getOrder_id();
    }

    //配送中心微服务查询商品销量
    @Override
    public List<PurchaseBean> getPurchaseList() {
        return orderMapper.getPurchaseList();
    }

    //配送中心查询客户总数量
    @Override
    public Integer getUserNum() {
        return orderMapper.getUserNum();
    }

    @Override
    public void changeDeliveryStatus(String order_id, String status) {
        Order order = orderMapper.selectByPrimaryKey(order_id);
        order.setDelivery_status(status);
        orderMapper.updateByPrimaryKey(order);
    }

    /**
     * 远程查询缺货
     */
    @Override
    public Boolean checkStockOutRemote(OrderDTO orderDTO) {
        Customer_address customer_address = addressMapper.selectByPrimaryKey(orderDTO.getCustomer_id(), orderDTO.getOrderForm().getAddress_choice());
        String receiver_address = customer_address.getReceiver_address();
        receiver_address=receiver_address.replace("/", "");
        return storeRoomServer.checkStockOut(receiver_address, orderDTO.getCommodity_id(), orderDTO.getOrderForm().getCommodity_num());
    }


    @Override
    public Boolean checkStockOutByTransfer(Order order) {
        Transfer transfer = dispatchServer.findByOrderId(order.getOrder_id());
        return storeRoomServer.checkStockOutByStoreroomId(transfer.getStoreroom_id(), order.getCommodity_id(), order.getCommodity_num());
    }

    @Override
    public void changeOrderStatus(String order_id, String status) {
        Order order = orderMapper.selectByPrimaryKey(order_id);
        order.setOrder_status(status);
        orderMapper.updateByPrimaryKey(order);
    }

}
